Skip to content

Use Azure Resource Manager for database/container commands#75

Open
mkrueger wants to merge 2 commits intomainfrom
feat/arm-resource-commands
Open

Use Azure Resource Manager for database/container commands#75
mkrueger wants to merge 2 commits intomainfrom
feat/arm-resource-commands

Conversation

@mkrueger
Copy link
Copy Markdown
Contributor

@mkrueger mkrueger commented May 6, 2026

Summary

Database and container management commands now use Azure Resource Manager (ARM) when available, and fall back to the Cosmos DB data plane when no ARM context is attached. Item-level commands continue to use the data plane.

This restores full functionality for emulator / account-key / static-token connections while preferring ARM for Entra ID flows where it gives better RBAC and control-plane semantics.

What changed

New core types

  • ArmCosmosContext — carries ArmClient, SubscriptionId, ResourceGroupName, AccountName, Uri AccountEndpoint, and the resolved CosmosDBAccountResource.
  • CosmosArmResourceProvider — ARM-only helpers (create, delete, get, enumerate, partition-key paths, ARM JSON read/write).
  • CosmosResourceFacade — chooses ARM vs data plane per call by inspecting state.ArmContext.

Connection flow

  • ShellInterpreter.ConnectAsync accepts optional subscriptionId / resourceGroupName / accountName and attaches an ArmCosmosContext on token-credential paths (VS Code, MI, browser, device code, DAC).
  • Explicit coordinates → bind directly. Partial coordinates → throw. Missing coordinates → discover by matching DocumentEndpoint across accessible subscriptions (errors only if multiple match).
  • Account-key, COSMOSDB_SHELL_TOKEN, and emulator connections do not attach ARM context and now use the data plane fallback.

Routed commands

Command ARM path Data-plane fallback
ls, completion account.GetCosmosDBSqlDatabases() / containers client.GetDatabaseQueryIterator / GetContainerQueryIterator
cd, validators GetIfExistsAsync Database.ReadAsync / Container.ReadContainerAsync
mkdb, mkcon CreateOrUpdateAsync CreateDatabaseIfNotExistsAsync / CreateContainerIfNotExistsAsync
rmdb, rmcon Delete*Async Database.DeleteAsync / Container.DeleteContainerAsync
settings <con> ARM container + ARM throughput ReadContainerAsync + ReadThroughputAsync
indexpolicy ARM update via ModelReaderWriter ReplaceContainerAsync via Newtonsoft.Json
rm, replace, item ls data plane (always) – ARM only used for partition-key path metadata when attached data plane
settings (account overview) data plane (always) same

CLI / startup options

  • New interactive options on connect: --subscription, --resource-group, --account
  • New startup options on the binary: --connect-subscription, --connect-resource-group, --connect-account

Docs

  • README.md, docs/commands.md, docs/connect.md, docs/mcp.md, docs/navigation.md updated to describe the hybrid model.

Validation

  • dotnet build of both projects: clean
  • dotnet test --filter "Category!=Emulator": 868 passed, 4 skipped, 0 failed (CosmosDBShell.Tests.dll)
  • Emulator-tagged integration tests not exercised in this change

Notes / follow-ups

  • MakeContainerCommand.CreateContainerProperties and MakeDbCommand.CreateThroughputProperties are no longer called by production code, but are retained because existing unit tests still cover them; happy to remove them and update those tests in a follow-up.
  • CosmosArmResourceProvider.RequireContext and the error-arm-context-required localization key are now unused (the facade no longer fails closed). Left in place for now; can be removed in a follow-up if preferred.

Database and container management operations now go through Azure
Resource Manager when the connection has an ARM context, and fall back
to the Cosmos DB data plane otherwise. Item-level operations remain on
the data plane.

* Add ArmCosmosContext, CosmosArmResourceProvider, and a hybrid
  CosmosResourceFacade that picks ARM or data plane per call.
* Attach an ARM context on token-credential connect flows; support
  explicit --subscription/--resource-group/--account and endpoint-based
  discovery, with the account-key / static-token / emulator paths
  transparently using the data plane.
* Route ls, cd, mkdb, mkcon, rmdb, rmcon, settings, indexpolicy, the
  existence validators, partition key reads for rm/replace, and tab
  completion through the facade.
* Add --connect-subscription / --connect-resource-group /
  --connect-account startup options and surface ARM coordinates in the
  connect command output.
* Update README and docs to describe the hybrid model.
@mkrueger mkrueger requested review from a team and Copilot May 6, 2026 08:49
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a hybrid “control plane vs data plane” resource model for Cosmos DB shell operations: database/container management prefers Azure Resource Manager (ARM) when an ARM context is available (Entra ID flows), while preserving full functionality for emulator/account-key/static-token connections by falling back to the Cosmos DB data plane.

Changes:

  • Adds an ARM context (ArmCosmosContext) and ARM resource helpers (CosmosArmResourceProvider), then routes database/container operations through a hybrid facade (CosmosResourceFacade).
  • Extends connection/startup options to optionally supply ARM coordinates (--subscription, --resource-group, --account and --connect-* equivalents) and propagates ARM context through navigation state.
  • Updates commands/docs/help text to reflect the hybrid model and routes ls/cd/mkdb/mkcon/rmdb/rmcon/settings/indexpolicy accordingly.

Reviewed changes

Copilot reviewed 32 out of 32 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
README.md Documents ARM preference for database/container management with Entra ID connections.
docs/navigation.md Adds startup option documentation and example for explicit ARM context at startup.
docs/mcp.md Documents ARM-vs-data-plane execution model for MCP sessions and associated risk guidance.
docs/connect.md Adds section describing ARM context attachment/discovery and explicit coordinate usage.
docs/commands.md Notes hybrid ARM/data-plane behavior for management commands.
Directory.Packages.props Adds ARM SDK dependencies (Azure.ResourceManager + CosmosDB) and System.ClientModel.
CosmosDBShell/Program.cs Wires new startup options into ConnectAsync.
CosmosDBShell/lang/en.ftl Adds new connect option descriptions/help text + ARM-context error string.
CosmosDBShell/CosmosDBShell.csproj Adds ARM SDK package references for the main tool.
CosmosDBShell/Azure.Data.Cosmos.Shell.Util/LocalizableSentenceBuilder.cs Adds localized help accessors for new startup options.
CosmosDBShell/Azure.Data.Cosmos.Shell.States/DatabaseState.cs Propagates optional ARM context through database navigation state.
CosmosDBShell/Azure.Data.Cosmos.Shell.States/ContainerState.cs Propagates optional ARM context through container navigation state.
CosmosDBShell/Azure.Data.Cosmos.Shell.States/ConnectedState.cs Stores ARM context on connected state and disposes Cosmos client.
CosmosDBShell/Azure.Data.Cosmos.Shell.Core/ThroughputAvailability.cs New enum to represent throughput read outcomes (available/not configured/unavailable).
CosmosDBShell/Azure.Data.Cosmos.Shell.Core/ShellInterpreter.cs Attaches ARM context during Entra ID connection flows and stores it on state.
CosmosDBShell/Azure.Data.Cosmos.Shell.Core/CosmosResourceFacade.cs Implements ARM-first, data-plane-fallback resource operations for db/container.
CosmosDBShell/Azure.Data.Cosmos.Shell.Core/CosmosCompleteCommand.cs Routes completions for db/container names through the hybrid facade.
CosmosDBShell/Azure.Data.Cosmos.Shell.Core/CosmosCommand.cs Routes existence checks and enumeration helpers through the hybrid facade.
CosmosDBShell/Azure.Data.Cosmos.Shell.Core/CosmosArmResourceProvider.cs Implements ARM discovery/CRUD/enumeration and ARM JSON read/write helpers.
CosmosDBShell/Azure.Data.Cosmos.Shell.Core/ContainerSettingsView.cs Adds a view model used to print container settings across ARM/data-plane.
CosmosDBShell/Azure.Data.Cosmos.Shell.Core/ArmCosmosContext.cs New type carrying ArmClient + resolved Cosmos account resource identity.
CosmosDBShell/Azure.Data.Cosmos.Shell.Commands/SettingsCommand.cs Switches container settings to use facade-provided view; updates MCP JSON payload.
CosmosDBShell/Azure.Data.Cosmos.Shell.Commands/RmDbCommand.cs Routes database deletion through hybrid facade and preserves ARM context on state transition.
CosmosDBShell/Azure.Data.Cosmos.Shell.Commands/RmContainerCommand.cs Routes container deletion through hybrid facade.
CosmosDBShell/Azure.Data.Cosmos.Shell.Commands/RmCommand.cs Uses hybrid partition-key-path resolution while keeping item operations data-plane.
CosmosDBShell/Azure.Data.Cosmos.Shell.Commands/ReplaceCommand.cs Uses hybrid partition-key-path resolution for item replace.
CosmosDBShell/Azure.Data.Cosmos.Shell.Commands/MakeDbCommand.cs Routes database creation through hybrid facade and standardizes output.
CosmosDBShell/Azure.Data.Cosmos.Shell.Commands/MakeContainerCommand.cs Routes container creation through hybrid facade; adds PK path parsing helper.
CosmosDBShell/Azure.Data.Cosmos.Shell.Commands/ListCommand.cs Routes db/container listing and PK path lookup through hybrid facade.
CosmosDBShell/Azure.Data.Cosmos.Shell.Commands/IndexPolicyCommand.cs Routes indexing policy read/write through hybrid facade (ARM or data-plane).
CosmosDBShell/Azure.Data.Cosmos.Shell.Commands/ConnectCommand.cs Adds connect options for ARM coordinates; prints ARM account id when available.
CosmosDBShell/Azure.Data.Cosmos.Shell.Commands/CdCommand.cs Preserves ARM context when navigating between states.

Comment thread CosmosDBShell/Azure.Data.Cosmos.Shell.Core/CosmosResourceFacade.cs Outdated
Comment thread CosmosDBShell/Azure.Data.Cosmos.Shell.Core/CosmosArmResourceProvider.cs Outdated
Comment thread CosmosDBShell/Azure.Data.Cosmos.Shell.Core/CosmosArmResourceProvider.cs Outdated
Comment thread CosmosDBShell/Azure.Data.Cosmos.Shell.Commands/ConnectCommand.cs Outdated
Comment thread CosmosDBShell/Azure.Data.Cosmos.Shell.Commands/SettingsCommand.cs Outdated
Comment thread CosmosDBShell/Azure.Data.Cosmos.Shell.Commands/SettingsCommand.cs
- CosmosResourceFacade.GetPartitionKeyPathsAsync: fall back to ContainerProperties.PartitionKeyPath when PartitionKeyPaths is null/empty (matches GetContainerSettingsAsync).
- CosmosArmResourceProvider: throw ShellException with localized strings for incomplete and ambiguous ARM context instead of InvalidOperationException with hard-coded flag names.
- CosmosArmResourceProvider.GetDatabasesAsync/GetContainersAsync: accept and propagate CancellationToken; remove CancellationToken.None usage.
- CosmosArmResourceProvider.DiscoverContextAsync: short-circuit once a second matching account is found instead of enumerating all subscriptions/accounts.
- ConnectCommand: localize the 'ARM Account' info row via command-connect-info-arm-account.
- SettingsCommand/ContainerSettingsView: surface N/A for unknown min/max throughput (and omit them from the MCP JSON), and restore the geospatial configuration and full-text policy sections in the data-plane path. ARM SDK 1.4.0-beta.13 does not expose these on CosmosDBSqlContainerResourceInfo, so the ARM path leaves them unset.
- Strip trailing blank lines (SA1518) and split records into single-type files (SA1402).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants